package com.example.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class JsonInputOutputForm extends JFrame {
    private JTextArea inputField1;
    private JTextArea inputField2;
    private JTextArea outputArea;
    private static final String ENCRYPTION_KEY = "4cda261e6e82550ceb380d7f2b857f3e";
    private static final String DEFAULT_CRYPTOSIGN = "0424b272fdfb6a166add4d8acc1627a5b6237780ea6b86caa40d6c1d17a7270ea8943a0e2f18c14862742bebfbf676933e6f0345fd7817148e9037bcf482a8a02eb74c5fdb35a4b289f876d0235f1ee8cef69b749d6db94497140f339d1063ebe4e07043c9abddd262fb322e7daa2da5c0dc6810aed0e753a8eadfe0f109f582aa";

    public JsonInputOutputForm() {
        // 设置窗口标题
        setTitle("saas加解密工具");
        // 设置窗口大小
        setSize(1250, 1000);
        // 设置窗口关闭操作
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 使用BorderLayout布局管理器
        setLayout(new BorderLayout(10, 10));

        // 创建主面板 - 包含所有输入组件
        JPanel inputPanel = new JPanel();
        inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
        inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 创建la517-cryptosign输入面板
        JPanel signPanel = new JPanel(new BorderLayout(5, 5));
        inputField1 = new JTextArea(3, 50);
        inputField1.setLineWrap(true);
        inputField1.setWrapStyleWord(true);
        JScrollPane signScrollPane = new JScrollPane(inputField1);
        signPanel.add(new JLabel("la517-cryptosign: "), BorderLayout.NORTH);
        signPanel.add(signScrollPane, BorderLayout.CENTER);

        // 创建明文/加密串输入面板
        JPanel textPanel = new JPanel(new BorderLayout(5, 5));
        inputField2 = new JTextArea(3, 50);
        inputField2.setLineWrap(true);
        inputField2.setWrapStyleWord(true);
        JScrollPane textScrollPane = new JScrollPane(inputField2);
        textPanel.add(new JLabel("加密串/明文: "), BorderLayout.NORTH);
        textPanel.add(textScrollPane, BorderLayout.CENTER);

        // 添加输入面板到主输入面板
        inputPanel.add(signPanel);
        inputPanel.add(Box.createRigidArea(new Dimension(0, 10)));
        inputPanel.add(textPanel);

        // 创建按钮面板 - 使用FlowLayout并设置紧密间距
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
        buttonPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 40)); // 限制按钮区域高度

        // 创建解密按钮并添加事件监听器
        JButton decryptButton = new JButton("解密");
        buttonPanel.add(decryptButton);
        decryptButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    handleDecrypt();
                } catch (Exception ex) {
                    outputArea.setText("解密失败: " + ex.getMessage());
                    ex.printStackTrace();
                }
            }
        });

        // 创建加密按钮并添加事件监听器
        JButton encryptButton = new JButton("加密");
        buttonPanel.add(encryptButton);
        encryptButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    handleEncrypt();
                } catch (Exception ex) {
                    outputArea.setText("加密失败: " + ex.getMessage());
                    ex.printStackTrace();
                }
            }
        });

        // 创建重置按钮并添加事件监听器
        JButton resetButton = new JButton("重置");
        buttonPanel.add(resetButton);
        resetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                inputField1.setText("");
                inputField2.setText("");
                outputArea.setText("");
            }
        });

        // 创建输出框 - 增大结果显示区域
        outputArea = new JTextArea(30, 50);
        outputArea.setEditable(false);
        outputArea.setLineWrap(true);
        outputArea.setWrapStyleWord(true);
        JScrollPane outputScrollPane = new JScrollPane(outputArea);

        // 创建一个组合面板，包含输入区域和按钮区域
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
        topPanel.add(inputPanel);
        topPanel.add(Box.createRigidArea(new Dimension(0, 10))); // 输入区域和按钮之间的间距
        topPanel.add(buttonPanel);

        // 将组件添加到窗口
        add(topPanel, BorderLayout.NORTH);       // 顶部区域包含输入和按钮
        add(outputScrollPane, BorderLayout.CENTER); // 中间区域为结果显示，自动填充剩余空间
    }

    private void handleDecrypt() throws Exception {
        String input1 = inputField1.getText();
        String input2 = inputField2.getText();

        if (input1.isEmpty() || input2.isEmpty()) {
            outputArea.setText("请输入la517-cryptosign和加密串");
            return;
        }

        // 创建JSON格式的字符串
        String decryptSM4Key = SM2Util.decrypt(input1);
        String decrypt = SM4Util.decrypt(input2, decryptSM4Key);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

        try {
            // 尝试解析为JSON对象
            Object jsonObject = objectMapper.readValue(decrypt, Object.class);
            String formattedJson = objectMapper.writeValueAsString(jsonObject);
            outputArea.setText(formattedJson);
        } catch (Exception e) {
            // 如果不是有效的JSON，直接显示解密结果
            outputArea.setText(decrypt);
        }
    }

    private void handleEncrypt() throws Exception {
        String plaintext = inputField2.getText();

        if (plaintext.isEmpty()) {
            outputArea.setText("请输入需要加密的明文");
            return;
        }

        // 使用固定密钥进行加密
        String encrypted = SM4Util.encrypt(plaintext, ENCRYPTION_KEY);
        outputArea.setText(encrypted);

        // 将默认值填充到la517-cryptosign输入框
        inputField1.setText(DEFAULT_CRYPTOSIGN);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new JsonInputOutputForm().setVisible(true);
        });
    }
}